const fs = require('fs');
const path = require('path');
const { EOL } = require('os');
const { log } = require('../../log');

function openBrowser(url) {
  const opn = require('opn');
  const homedir = require('os').homedir();
  let browser = 'google-chrome';
  let userDir;

  const { platform } = process;
  if (platform === 'darwin') {
    browser = 'google chrome';
    userDir = `${homedir}/WlkChromeDevUserData`;
  } else if (platform === 'win32') {
    browser = 'chrome';
    userDir = `${homedir}\\WlkChromeDevUserData`;
  }
  opn(url, {
    app: [browser, '--disable-web-security', `--user-data-dir=${userDir}`]
  });
}
function requireJSON(filePath) {
  try {
    return JSON.parse(fs.readFileSync(filePath, 'utf8'));
  } catch (error) {
    log(`获取 ${filePath} 出错，错误信息：${error}`);
    return {};
  }
}

const defaultWeCodeJson = {
  eslint: false,
  debug: false,
  webpackConfig: {
    stats: false
  },
  devServer: {},
  htmlPlugin: {
    head: {
      links: []
    },
    body: {
      scripts: []
    }
  }
};
const defaultDevServer = {
  port: 8080,
  host: '0.0.0.0',
  open: false
}

function getWeCodeConfig(rootPath) {
  let filePath = '';
  // 1、历史版本约定地址 wecode.json 地址
  const wecodeFilePath = path.join(rootPath, 'wecode.json');
  const wecodeJson = { ...defaultWeCodeJson };
  if (fs.existsSync(wecodeFilePath)) {
    filePath = wecodeFilePath;
    let currentWecodeJson = requireJSON(wecodeFilePath);
    Object.assign(wecodeJson, currentWecodeJson);
  }
  // 2、新版约定的配置在 src/app.json 中
  const appFilePath = path.join(rootPath, 'src/app.json');
  if (fs.existsSync(appFilePath)) {
    filePath = appFilePath;
    const appJson = requireJSON(appFilePath);
    if (appJson && appJson.runtime) { // 合并 wecodeJson 配置
      Object.assign(wecodeJson, appJson.runtime);
    }
  }

  if (wecodeJson.devServer) {
    wecodeJson.devServer = Object.assign({}, defaultDevServer, wecodeJson.devServer);
  }
  // 兼容旧版配置
  if (wecodeJson.port) {
    wecodeJson.devServer.port = wecodeJson.port;
  }
  if (wecodeJson.host) {
    wecodeJson.devServer.host = wecodeJson.host;
  }
  if (wecodeJson.openBrowser) {
    wecodeJson.devServer.open = wecodeJson.openBrowser;
  }
  return { wecodeJson, wecodeFilePath: filePath };
}

function getIndexURLAndPublicPath(appPath) {
  if (process.env.WECODE_ENV === 'development') { // 本地调试
    return {
      baseURL: 'index.html',
      webpackPublicPath: '/'
    }
  }
  // 本地开发打开地址是通过plugin.json配置的indexURL而定
  let plugin = null;
  try {
    plugin = require(getPluginPath(appPath));
  } catch (error) {
    log(error);
  }
  let _indexURL = 'index.html'; // 默认值
  if (plugin && plugin.indexURL) {
    _indexURL = plugin.indexURL.replace(/h5:\/\/([^/])*\//, ''); // 打包时，根据 plugin.indexURL 配置
  }

  const pageLevels = _indexURL.split('/');
  let publicPath = './'; // 默认页面只有一级
  if (pageLevels.length > 0) {
    let tempPublicPath = '';
    for (let i = 1; i < pageLevels.length; i++) {
      tempPublicPath += '../';
    }
    publicPath = tempPublicPath;
  }
  return { baseURL: _indexURL, webpackPublicPath: publicPath };
}

/**
 * 保存配置文件
 * @param {*} obj 
 */
function saveJsonFile(filePath, obj) {
  const jsonData = requireJSON(filePath);
  try {
    Object.assign(jsonData, obj);
    fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2) + EOL);
  } catch (error) {
    log(error);
  }
}

/**
 * 报错时，发送错误消息
 * @param {*} err 
 */
function processSendError(err) {
  if (process && process.send) {
    let requestMessage = null;
    try {
      requestMessage = JSON.parse(process.env.WEOCDE_PROCESS_MESSAGE);
    } catch (error) {
      log(error);
    }
    process.send({
      status: 'error', request: requestMessage, message: {
        tip: 'Build fail.',
        details: err
      }
    });
  }
}

/**
 * 检查端口是否在合法范围
 * @param {number} port 
 */
function checkPortVaild(port) {
  if (port < 8000 || port > 9000) {
    error('the prot allows a range of 8001 to 9000.');
    process.exit();
  }
}

/**
 * 获取 plugin.json 文件地址
 * @param {*} appPath 项目根目录
 */
function getPluginPath(appPath) {
  const pluginFilePath = path.join(appPath, '.wecode/plugin.json');
  if (fs.existsSync(pluginFilePath)) {
    return pluginFilePath;
  }
  const oldPluginFilePath = path.join(appPath, 'plugin.json');
  if (fs.existsSync(oldPluginFilePath)) {
    return oldPluginFilePath;
  }
  return '';
}

module.exports = {
  openBrowser,
  requireJSON,
  getWeCodeConfig,
  getIndexURLAndPublicPath,
  saveJsonFile,
  processSendError,
  checkPortVaild,
  getPluginPath
}
